﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using ST.Buz.Base;
using ST.Buz.Base.Entity;
using ST.Buz.Base.Enums;
using ST.Buz.Base.ViewModel;
using ST.Common.Data;
using ST.Common.Util;
using ST.Common.Util.Model;
using ST.Common.Util.Mvc;
using System;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using System.Linq;
using System.Text.RegularExpressions;

namespace ST.Buz.Service
{
	/// <summary>
	/// 
	/// </summary>
	public partial interface IServiceSysBuzRowNum
	{
		/// <summary>
		/// 获取编辑详细信息
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		Sys_BuzRowNum GetEditDetail(int id, UserSession sessionCurrent);

		/// <summary>
		/// 获取查看详细信息
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		Sys_BuzRowNum GetViewDetail(int id, UserSession sessionCurrent);

		/// <summary>
		/// 删除
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		bool Delete(int id, UserSession sessionCurrent);

		/// <summary>
		/// 批量删除
		/// </summary>
		/// <returns></returns>
		bool BatchDelete(int[] ids, UserSession sessionCurrent);

		/// <summary>
		/// 分页列表
		/// </summary>
		PageData GetPageList(VMS_Sys_BuzRowNum searchModel);

		/// <summary>
		/// 新增或修改保存
		/// </summary>
		int AddOrUpdate(Sys_BuzRowNum model, UserSession sessionCurrent);

		/// <summary>
		/// 获取下一个编码（并更新数据库的当前值，用于直接保存）
		/// </summary>
		/// <param name="buzCatID">一般指根据表的某一列进行编号，如分类</param>
		/// <param name="buzCode">一般指具体的某一项编号，一条记录可能会生成多项编号如会员号、卡号</param>
		/// <returns></returns>
		string GetNextWithinTrans(int buzCatID, string buzCode);

		/// <summary>
		/// 获取下一个编码（不更新数据库中的当前值，用于临时获取一下）
		/// </summary>
		/// <param name="buzCatID">一般指根据表的某一列进行编号，如分类</param>
		/// <param name="buzCode">一般指具体的某一项编号，一条记录可能会生成多项编号如会员号、卡号</param>
		/// <returns></returns>
		string GetNext(int buzCatID, string buzCode);
	}

	public partial class ServiceSysBuzRowNum
	{
		private readonly IServiceSysLog serviceSysLog;

		public ServiceSysBuzRowNum(BuzContext ctx,
			IServiceSysLog _serviceSysLog,
			ILogger<ServiceSysBuzRowNum> log)
		{
			serviceSysLog = _serviceSysLog;

			context = ctx;
			logger = log;
		}

		/// <summary>
		/// 获取业务编码详细信息
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public Sys_BuzRowNum GetViewDetail(int id, UserSession sessionCurrent)
		{
			try
			{
				var model = context.SysBuzRowNum.SingleOrDefault(m => m.ID == id);
				if (model == null)
				{
					throw new BuzException("未找到相关记录");
				}
				return model;
			}
			catch (ArgumentException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取对象信息出错");
				throw new BuzException("获取对象信息失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}

		public Sys_BuzRowNum GetEditDetail(int id, UserSession sessionCurrent)
		{
			return GetViewDetail(id, sessionCurrent);
		}

		/// <summary>
		/// 删除业务编码
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public bool Delete(int id, UserSession sessionCurrent)
		{
			bool success = false;
			try
			{
				//if (logger.IsEnabled(LogLevel.Debug))
				//{
				//	logger.LogDebug($"参数->id:{id}，state:{state}，remark:{remark}");
				//}
				if (sessionCurrent == null)
				{
					throw new BuzException("用户会话不能为空");
				}

				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						DateTime dtNow = DateTime.Now;
						string ip = GetRequestIP();

						Sys_BuzRowNum modelOld = Get(id, true);
						Delete(modelOld);

						serviceSysLog.Add(sessionCurrent, ip, $"删除业务编码信息，原信息：", modelOld, dtNow);
						#endregion

						trans.Commit();
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}

				success = true;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "删除业务编码出错");
				throw new BuzException("删除业务编码失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return success;
		}

		/// <summary>
		/// 批量删除业务编码
		/// </summary>
		/// <returns></returns>
		public bool BatchDelete(int[] ids, UserSession sessionCurrent)
		{
			bool success = false;
			try
			{
				//if (logger.IsEnabled(LogLevel.Debug))
				//{
				//	logger.LogDebug($"参数->id:{id}，state:{state}，remark:{remark}");
				//}
				if (sessionCurrent == null)
				{
					throw new BuzException("用户会话不能为空");
				}

				if (ids == null || ids.Length == 0)
				{
					throw new BuzException("参数不能为空");
				}

				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						DateTime dtNow = DateTime.Now;
						string ip = GetRequestIP();

						foreach (int id in ids)
						{
							Sys_BuzRowNum modelOld = Get(id, true);
							Delete(modelOld);

							serviceSysLog.Add(sessionCurrent, ip, $"批量删除业务编码信息，原信息：", modelOld, dtNow);
						}

						context.SaveChanges();
						#endregion

						trans.Commit();
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}

				success = true;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "批量删除业务编码出错");
				throw new BuzException("批量删除业务编码失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return success;
		}

		/// <summary>
		/// 检验编码是否可用
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public bool ValidateCode(int id, string code, UserSession sessionCurrent)
		{
			try
			{
				//if (logger.IsEnabled(LogLevel.Debug))
				//{
				//	logger.LogDebug($"参数->id:{id}，state:{state}，remark:{remark}");
				//}
				if (sessionCurrent == null)
				{
					throw new BuzException("用户会话不能为空");
				}
				if (string.IsNullOrEmpty(code))
				{
					throw new BuzException("业务编码编码不能为空");
				}
				//if (id == 0)
				//{
				//	return !context.SysBuzRowNum.Any(m => m.Code == code);
				//}
				//var lst = context.SysBuzRowNum.Where(m => m.Code == code).AsNoTracking().ToList();
				//if (lst.Count == 0)
				//{
				//	return true;
				//}
				//foreach (var i in lst)
				//{
				//	if (i.ID != id)
				//	{
				//		return false;
				//	}
				//}

				return true;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "检验业务编码编码是否可用出错");
				throw new BuzException("检验业务编码编码是否可用失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}

		/// <summary>
		/// 分页列表
		/// </summary>
		public PageData GetPageList(VMS_Sys_BuzRowNum searchModel)
		{
			PageData result = null;
			try
			{
				searchModel.Validate();

				var query = from u in context.SysBuzRowNum
							select u;
				if (!string.IsNullOrWhiteSpace(searchModel.name))
				{
					query = query.Where(m => EF.Functions.Like(m.Name, "%" + searchModel.name + "%"));
				}
				if (searchModel.ids != null && searchModel.ids.Length > 0)
				{
					query = query.Where(m => searchModel.ids.Contains(m.ID));
				}
				if (searchModel.type.HasValue && searchModel.type.Value > 0)
				{
					query = query.Where(m => m.BuzType == searchModel.type.Value);
				}

				switch (searchModel.sortby)
				{
					//case "Code":
					//	////数据库分页，不支持多表
					//	//query = query.OrderByDescending(e => EF.Property<object>(e, sortOrder));
					//	////内存分页
					//	////query = query.OrderByDescending(e => e.GetType().GetProperty(sortOrder).GetValue(e, null));
					//	query = searchModel.orderby == Common.Util.Mvc.SortOrder.Ascending ? query.OrderBy(e => e.Code) : query.OrderByDescending(e => e.Code);
					//	break;
					//case "Name":
					//	query = searchModel.orderby == Common.Util.Mvc.SortOrder.Ascending ? query.OrderBy(e => e.Name) : query.OrderByDescending(e => e.Name);
					//	break;
					//case "Reserved":
					//	query = searchModel.orderby == Common.Util.Mvc.SortOrder.Ascending ? query.OrderBy(e => e.Reserved) : query.OrderByDescending(e => e.Reserved);
					//	break;
					//case "Visible":
					//	query = searchModel.orderby == Common.Util.Mvc.SortOrder.Ascending ? query.OrderBy(e => e.Visible) : query.OrderByDescending(e => e.Visible);
					//	break;
					//case "Sort":
					//	query = searchModel.orderby == Common.Util.Mvc.SortOrder.Ascending ? query.OrderBy(e => e.Sort) : query.OrderByDescending(e => e.Sort);
					//	break;
					default:
						query = query.OrderBy(e => e.Sort).ThenBy(e => e.ID);
						break;
				}
				result = new PageData(searchModel.pnum.Value, searchModel.psize.Value);
				result.Load(query);
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取分页数据出错");
				throw new BuzException("获取分页数据失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return result;
		}

		/// <summary>
		/// 新增或修改保存
		/// </summary>
		public int AddOrUpdate(Sys_BuzRowNum model, UserSession sessionCurrent)
		{
			try
			{
				//if (logger.IsEnabled(LogLevel.Debug))
				//{
				//	logger.LogDebug($"参数->id:{id}，state:{state}，remark:{remark}");
				//}
				if (sessionCurrent == null)
				{
					throw new BuzException("用户会话不能为空");
				}
				if (model == null)
				{
					throw new BuzException("参数不能为空");
				}

				if (string.IsNullOrEmpty(model.Code))
				{
					throw new BuzException("编码类型不能为空");
				}

				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						DateTime dtNow = DateTime.Now;
						string ip = GetRequestIP();

						if (model.ID > 0)
						{
							var modelOld = Get(model.ID, true);
							if (modelOld.Freezed)
							{
								throw new BuzException("该业务编码不允许修改");
							}
							if (modelOld.Reserved)
							{
								model.BuzType = modelOld.BuzType;
								model.Code = modelOld.Code;//系统保留的基本信息不能修改
							}
							model.Current = modelOld.Current;//有些信息不能修改
							model.Step = modelOld.Step;//有些信息不能修改
							if (!string.IsNullOrEmpty(model.Code))
							{
								if (context.SysBuzRowNum.Any(m => m.BuzType == model.BuzType && m.Code == model.Code && m.ID != model.ID))
								{
									throw new BuzException("业务类型和编码类型重复");
								}
							}
							Update(model);
						}
						else
						{
							if (!string.IsNullOrEmpty(model.Code))
							{
								if (context.SysBuzRowNum.Any(m => m.BuzType == model.BuzType && m.Code == model.Code))
								{
									throw new BuzException("业务类型和编码类型重复");
								}
							}
							model.AddDate = dtNow;
							model.AddManID = sessionCurrent.UserID;
							model.AddManName = sessionCurrent.UserName;
							Add(model);
						}

						#endregion

						trans.Commit();

						return model.ID;
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "保存对象信息出错");
				throw new BuzException("数据库保存失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}

		/// <summary>
		/// 获取下一个编码，并更新数据库的当前值
		/// </summary>
		/// <param name="buzCatID">一般指根据表的某一列进行编号，如分类</param>
		/// <param name="buzCode">一般指具体的某一项编号，一条记录可能会生成多项编号如会员号、卡号</param>
		/// <returns></returns>
		public string GetNextWithinTrans(int buzCatID, string buzCode)
		{
			var model = context.SysBuzRowNum.SingleOrDefault(m => m.BuzType == buzCatID && m.Code == buzCode);
			if (model == null)
			{
				model = context.SysBuzRowNum.FirstOrDefault(m => m.Code == buzCode);
			}
			if (model == null)
			{
				throw new BuzException("未设置相关业务编码模板:" + buzCode);
			}

			DateTime dtNow = DateTime.Now;
			var num = model.Current.ToString();
			var rowNum = model.RuleTpl.Replace("${no}", num.Length < model.MinLen ? num.PadLeft(model.MinLen, '0') : num);
			var matches = Regex.Matches(rowNum, "y{2,4}|MM|dd|HH|mm|ss");
			if (matches != null && matches.Count > 0)
			{
				for (int i = 0; i < matches.Count; i++)
				{
					rowNum = rowNum.Replace(matches[i].Value, dtNow.ToString(matches[i].Value));
				}
			}
			rowNum = Regex.Replace(rowNum, "\\${(\\w+)\\}", (m) => m.Groups[1].Value);
			if (string.IsNullOrEmpty(rowNum))
			{
				throw new BuzException("业务编码为空");
			}
			context.Database.ExecuteSqlRaw("UPDATE Sys_BuzRowNum SET [Current]=[Current]+[Step] WHERE ID={0}", model.ID);
			return rowNum;
		}

		/// <summary>
		/// 获取下一个编码，并更新数据库的当前值
		/// </summary>
		/// <param name="buzCatID">一般指根据表的某一列进行编号，如分类</param>
		/// <param name="buzCode">一般指具体的某一项编号，一条记录可能会生成多项编号如会员号、卡号</param>
		/// <returns></returns>
		public string GetNext(int buzCatID, string buzCode)
		{
			try
			{
				return GetNextWithinTrans(buzCatID, buzCode);
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "生成业务编码出错");
				throw new BuzException("生成业务编码失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}
	}
}